import { CqkjMap } from "./Basic/CqkjMap"
import { CoordinateIndication } from "./MapElement/CoordinateIndication"
import { TileMap } from "./MapElement/TileMap"
import { getCustomRef } from "./Util/vue"
import foreionAirspace from "./Asset/foreionAirspace.json";
import { ForeignAirspace } from "./MapElement/ForeignAirspace";
import { CivilAirline } from "./MapElement/CivilAirline";
import { FlyArea } from "./MapElement/FlyArea";
import { registerPainter } from 'zrender'
import CanvasPainter from 'zrender/lib/canvas/Painter'
import { LegendData } from "./DataElement/LegendData";
import { Grid2Data } from "./DataElement/Grid2Data";
import { Grid3Data } from "./DataElement/Grid3Data";
import { Horizontal_Isosurface_Material, Space_Profile_Material, Space_Volume_Material, Vertical_Profile_Material } from "./materials";
import { SpaceHorizontalProfile } from "./MapElement/SpaceHorizontalProfile";
import { GroundIsosurface } from "./MapElement/GroundIsosurface";
import { SpaceVerticalProfile } from "./MapElement/SpaceVerticalProfile";
import { AirLine } from "./MapElement/Airline";
import { Airspace } from "./MapElement/Airspace";
import { SpaceVolume } from "./MapElement/SpaceVolume";

registerPainter('canvas', CanvasPainter)
/** 地图实例 */
export const map = new CqkjMap();

(window as any).map = map


/**
 * 挂载地图
 * @param id Div容器id 
 */
export function mountMap(id: string) {
  map.addTo(id)
  map.setView(120, 31.5, 5)
}

/** 坐标指示器 */
new CoordinateIndication(map)



/** 地图模式 可选值:'2D'|'3D' */
export const mapMode = getCustomRef(map.mode, (val) => {
  map.mode = val
})

/** 瓦片地图集合 */
const tilemaps = new Map<string, TileMap[]>()

tilemaps.set('默认底图', [new TileMap(map, {
  name: '默认底图',
  url: 'https://api.mapbox.com/styles/v1/zy-01/clbbopz4y000q15mslpuydwy2/tiles/256/{z}/{x}/{y}?access_token=pk.eyJ1IjoienktMDEiLCJhIjoiY2xiYm9qZmxzMGthZzN4bG1lMGd4dGs1YyJ9.gbzGyrJNb3U0zQMR_a2EGQ',
})])

tilemaps.set('行政区划', [new TileMap(map, {
  name: '行政底图',
  show: false,
  url: 'http://t{s}.tianditu.gov.cn/DataServer?T=vec_w&X={x}&Y={y}&L={z}&tk=0a9cfb135e61b353ba6c8b4cb3386101'
}),
new TileMap(map, {
  name: '行政标注',
  show: false,
  url: 'http://t{s}.tianditu.gov.cn/DataServer?T=cva_w&X={x}&Y={y}&L={z}&tk=0a9cfb135e61b353ba6c8b4cb3386101',
  z: 10
})])

tilemaps.set('遥感影像', [new TileMap(map, {
  name: '遥感底图',
  show: false,
  url: 'http://t{s}.tianditu.gov.cn/DataServer?T=img_w&X={x}&Y={y}&L={z}&tk=0a9cfb135e61b353ba6c8b4cb3386101'
}),
new TileMap(map, {
  name: '遥感标注',
  show: false,
  url: 'http://t{s}.tianditu.gov.cn/DataServer?T=cia_w&X={x}&Y={y}&L={z}&tk=0a9cfb135e61b353ba6c8b4cb3386101',
  z: 10
})])

tilemaps.set('地形地貌', [new TileMap(map, {
  name: '地形底图',
  show: false,
  url: 'http://t{s}.tianditu.gov.cn/DataServer?T=ter_w&X={x}&Y={y}&L={z}&tk=0a9cfb135e61b353ba6c8b4cb3386101'
}),
new TileMap(map, {
  name: '地形标注',
  show: false,
  url: 'http://t{s}.tianditu.gov.cn/DataServer?T=cta_w&X={x}&Y={y}&L={z}&tk=0a9cfb135e61b353ba6c8b4cb3386101',
  z: 10
})])


/** 底图服务 可选值:'默认底图'|'行政区划'|'遥感影像'|'地形地貌' */
export const basicMap = getCustomRef('默认底图', (val) => {
  tilemaps.forEach((ts, k) => {
    const show = val == k
    ts.forEach(t => t.show = show)
  })
})

/** 国外领空 */
new ForeignAirspace(map, [foreionAirspace.features[0].geometry.coordinates])


/** 民用航线 */
new CivilAirline(map, {
  name: '民用航线',
  show: true,
  points: [
    [115.2576, 28.7484],
    [115.4553, 30.2591],
    [116.2354, 31.1282],
    [117.8174, 31.8496],
  ],
  height: 4000,
})


/** 飞行情报区 */
new FlyArea(map)


/** 图例字典 */
export const legends = new Map<string, LegendData>()
// legends.set('温度', LegendData.fromThresholds([[-40, "#4B0098"], [-36, "#2E00C0"], [-32, "#1100E7"], [-28, "#0017F8"], [-24, "#044E96"], [-20, "#06864B"], [-16, "#18B81F"], [-12, "#6BD16F"], [-8, "#BDEBBF"], [-4, "#FFFFFF"], [4, "#FFFFBB"], [8, "#FFFF66"], [12, "#F9F910"], [16, "#FFE900"], [20, "#FFCC00"], [24, "#FFB000"], [28, "#FF8400"], [32, "#FF4D00"], [36, "#FF2E00"], [40, "#FF0000"]], 1, "#430169"))
legends.set('温度', LegendData.fromThresholds([[-40, "#4B0098"], [-36, "#2E00C0"], [-32, "#1100E7"], [-28, "#0017F8"], [-24, "#044E96"], [-20, "#06864B"], [-16, "#18B81F"], [-12, "#6BD16F"], [-8, "#BDEBBF"], [-4, "#FFFFFF"], [4, "#FFFFBB"], [8, "#FFFF66"], [12, "#F9F910"], [16, "#FFE900"], [20, "#FFCC00"], [24, "#FFB000"], [28, "#FF8400"], [32, "#FF4D00"], [36, "#FF2E00"], [40, "#FF0000"]]))
// 地面等值面
const giso = new GroundIsosurface(map, {
  name: '地面等值面',
  show: true,
  material: Horizontal_Isosurface_Material
})

/** 当前图例类型 */
export const legend = getCustomRef('温度', (val) => {
  const ld = legends.get(val)
  if (ld) {
    Space_Profile_Material.uniforms.u_legend.value = ld.texture
    Space_Profile_Material.uniforms.u_range.value = ld.option.range
    Horizontal_Isosurface_Material.uniforms.u_legend.value = ld.texture
    Horizontal_Isosurface_Material.uniforms.u_range.value = ld.option.range
    Vertical_Profile_Material.uniforms.u_legend.value = ld.texture
    Vertical_Profile_Material.uniforms.u_range.value = ld.option.range
    Space_Volume_Material.uniforms.u_legend.value = ld.texture
    Space_Volume_Material.uniforms.u_range.value = ld.option.range
    giso.reflesh()
  }
}, true)



/** 设置三维空间格点数据 */
export async function setSpaceDataByPngs(data: [number, string][], step: number) {
  const grid2s = await Promise.all(data.map(async e => {
    return [e[0], await Grid2Data.fromPng(e[1], false, [256, 256])]
  }))
  if (grid2s[0][0] == 0) {
    const grid2 = grid2s.shift()![1] as Grid2Data
    Horizontal_Isosurface_Material.uniforms.u_min.value = grid2.option.box.min
    Horizontal_Isosurface_Material.uniforms.u_max.value = grid2.option.box.max
    Horizontal_Isosurface_Material.uniforms.u_data.value = grid2.texture
  }
  const grid3 = Grid3Data.fromGrid2Datas(grid2s.filter(e => e[1]) as [number, Grid2Data][], step)
  Space_Profile_Material.uniforms.u_min.value = grid3.option.box.min
  Space_Profile_Material.uniforms.u_max.value = grid3.option.box.max
  Space_Profile_Material.uniforms.u_data.value = grid3.texture
  Vertical_Profile_Material.uniforms.u_min.value = grid3.option.box.min
  Vertical_Profile_Material.uniforms.u_max.value = grid3.option.box.max
  Vertical_Profile_Material.uniforms.u_data.value = grid3.texture
  Space_Volume_Material.uniforms.u_min.value = grid3.option.box.min
  Space_Volume_Material.uniforms.u_max.value = grid3.option.box.max
  Space_Volume_Material.uniforms.u_data.value = grid3.texture
  giso.reflesh()
}


// 空间水平剖面
new SpaceHorizontalProfile(map, {
  name: '空间水平剖面',
  show: true,
  heights: [],
  material: Space_Profile_Material
})



/** 图例最小值过滤 */
export const legendMinFilter = getCustomRef(-50, (val) => {
  Space_Profile_Material.uniforms.u_filter.value[0] = val
  Space_Volume_Material.uniforms.u_filter.value[0] = val
  Vertical_Profile_Material.uniforms.u_filter.value[0] = val
  giso.reflesh()
  Horizontal_Isosurface_Material.uniforms.u_filter.value[0] = val
})

/** 图例最大值过滤 */
export const legendMaxFilter = getCustomRef(50, (val) => {
  Space_Profile_Material.uniforms.u_filter.value[1] = val
  Space_Volume_Material.uniforms.u_filter.value[1] = val
  Vertical_Profile_Material.uniforms.u_filter.value[1] = val
  giso.reflesh()
  Horizontal_Isosurface_Material.uniforms.u_filter.value[1] = val
})

export function showRouteProfile(routeName: string) {
  const route = map.elements.get(routeName) as AirLine
  if (route) {
    new SpaceVerticalProfile(map, {
      show: true,
      name: '航线剖面',
      material: Vertical_Profile_Material,
      path: route.option.points.map(e => [e.lon, e.lat])
    })
  }

}

export function showAirSpaceVolume(name: string) {
  const space = map.elements.get(name) as Airspace
  if (space) {
    new SpaceVolume(map, {
      show: true,
      name: '空域体积',
      material: Space_Volume_Material,
      path: space.option.points
    })
  }
}